package com.xiaoyu.cloudmusic.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.xiaoyu.cloudmusic.data.GlobalData;
import com.xiaoyu.cloudmusic.pojo.*;
import com.xiaoyu.cloudmusic.resp.*;
import com.xiaoyu.cloudmusic.resp.Creator;
import com.xiaoyu.cloudmusic.service.AccountsServiceImpl;
import com.xiaoyu.cloudmusic.service.PlayListServiceImpl;
import com.xiaoyu.cloudmusic.utils.*;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.SocketException;
import java.util.*;

@Controller
public class PlaylistController {
    @Autowired
    PlayListServiceImpl playListService;
    @Autowired
    AccountsServiceImpl accountsService;

//    获取推荐歌单
    @RequestMapping("/playList/recommend")
    @ResponseBody
    public Result getAllRecommend(){
        List<Recommend> recommends=playListService.getRandRecommend(8);
//        for (int i = 0; i < recommends.size(); i++) {
//
//        }
        return Result.ok().put("result",recommends);
    }
    // login 获取个性推荐歌单
    @RequestMapping("playList/resource")
    @ResponseBody
    public Result getAllResource() throws SocketException {
        List<Recommend> recommends=playListService.getRandRecommend(10);
        for (int i = 0; i < recommends.size(); i++) {
//              修改封面地址
            recommends.get(i).setPicUrl(AddressInvertUtil.localHostReplace(recommends.get(i).getPicUrl()));
        }
        return Result.ok().put("recommend",recommends);
    }
    //创建
    @RequestMapping("/playList/createplaylist")
    @ResponseBody
    public Result createPlayList(@RequestBody Object data, @RequestHeader("Authorization") String token) throws JsonProcessingException {
        Payload payload= JWTUtils.getToken(token);
        //按数据库中listId进行排序去id最大的那条返回出来并取到listid,下面id+1插入数据库
        //从大到小进行排序limit取第一个
        PlayListDetail last=playListService.getLastPlayListDetail();
        //获取当前时间并正确的格式化
        HashMap<String,String> hashMap= (HashMap<String, String>) data;
        String title=hashMap.get("title");
        String isPublic=hashMap.get("isPublic");
        String formattedDateTime = DataUtil.getFormatter("yyyyMMdd");
        //按照用户UUID、title、id、创建时间 创建一条信息，注意数据库中的增加数据和id数据的返回
        //向歌单数据库中插入一条数据（playlist）
        int result=playListService.addPlayList(payload.getUuid(), last.getListId()+1, title,formattedDateTime,isPublic);
        if(result!=1){
            return Result.error();
        }
        ListIdData listIdData=new ListIdData();
        listIdData.setId(last.getListId()+1);

        //判断歌单是否公开，公开则加入公开歌单表
        if(isPublic.equals("1")){
            Recommend recommend = new Recommend();
            recommend.setId(listIdData.getId());
            recommend.setName(title);
            recommend.setPicUrl(null);
            int res = playListService.addRecommend(recommend);
            if(res != 1){
                return Result.error();
            }
            return Result.ok().put("data",listIdData);
        }

        return Result.ok().put("data",listIdData);
    }
    //获取歌单详情
    /*
    * 2023/11/24:
    * 项目中发现歌曲可以单独放到一个表中，那样会方便管理，后面的话我们打算将歌单和歌曲表的关联另外放到
    * 一张表上进行记录，这样也好依照去进行增删改查！！！
    *
    * 他喵的，重构是真的痛苦，之前的表的字段没有考虑清楚，呜呜呜呜！！！！
    *
    * 现在下面的东西要进行修改了！！！！
    * */
    @RequestMapping("/playList/detail")
    @ResponseBody
    public Result getPlayListDetail(String uuid,int id) throws SocketException {
        /*TODO:tags问题！！！！！！
        * 喵的，我发现这里的tags竟然还要重构，因为要返回数组，我的想法还是用字符串！等下在JS前端操作一下这边
        * 传来的信息，后端也得处理这个问题——————————2023-11-22
        * 前端tags数组问题，字符串
        *
        * 这里又有一个问题，就是如果我的数据库中没数据，不能让前端报错！！！
        * 就是tagStr这个地方如果没有数据，要判断
        * */
        //这里传来的id是歌单的id,其中的tracks中歌曲已经获取到了，通过重构之后。
        //下面这个数据库返回参数，creator、trackCount是空的
        PlayListDetail playListDetail=playListService.getPlayListDetail(id);
        String tagsStr= playListDetail.getTagStr();//获取tags字符串
        List<String> tags= new ArrayList<>();
        if(tagsStr!=null){
            String[] strArr=tagsStr.split("-");//获得拆分字符串
            //将这个tags数组放进对象
            tags.addAll(Arrays.asList(strArr));
        }
        /**
         * 对用户访问歌单风格进行统计
         */
        GlobalDataUtil.countStyle(tags);
        System.out.println(GlobalData.musicStyleCountMap);

        playListDetail.setTags(tags);
        //获取到creator信息，通过UUID查询userinfo表
        Creator creator=new Creator();
        UserInfo userInfo=accountsService.findUserInfoByUUID(playListDetail.getUuid());
        creator.setAvatarUrl(AddressInvertUtil.localHostReplace(userInfo.getPhotoPath()));
        creator.setNickname(userInfo.getNickname());
        //将playListDetail对象数据填充好
        playListDetail.setCreator(creator);
        playListDetail.setTrackCount(playListDetail.getTracks().size());
        /**
         * 服务器本机地址替换
         */
        List<Song> tracks = playListDetail.getTracks();
        String coverImgUrl = playListDetail.getCoverImgUrl();
        for (Song track : tracks) {
//              修改歌曲地址
            track.setUrl(AddressInvertUtil.localHostReplace(track.getUrl()));
//              修改封面地址
            track.setPicUrl(AddressInvertUtil.localHostReplace(track.getPicUrl()));
        }
        playListDetail.setTracks(tracks);
        playListDetail.setCoverImgUrl(AddressInvertUtil.localHostReplace(coverImgUrl));
//      对歌单是否收藏状态进行查询
        playListDetail.setFavorites(playListService.isFavorites(uuid,id));
        return Result.ok().put("data",playListDetail);
    }
    //login 更新歌单信息
    @RequestMapping("/playList/update")
    @ResponseBody
    public Result updateMyPlayList(@RequestBody PlayListDetail playListDetail){//不需要token
//        System.out.println(playListDetail);
        //这里传入的数据直接可以去数据库中进行更改操作！
        int result=playListService.updateMyPlayList(playListDetail);
        if(result!=1){
            return Result.error();
        }
//       同步对公共歌单进行更新
        if(playListDetail.getIsPublic() == 1){
            Recommend recommend = new Recommend();
            recommend.setId(playListDetail.getListId());
            recommend.setName(playListDetail.getName());
            recommend.setPicUrl(playListDetail.getCoverImgUrl());
            int res = playListService.updateRecommend(recommend);
            if(res != 1){
                return Result.error();
            }
            return Result.ok();
        }
        return Result.ok();
    }
    //上传歌单封面
    @RequestMapping("/playList/coverupload")
    @ResponseBody
    public Result uploadPlayListImg(PlayListImgFormData playListImgFormData){
        //向数据库按照歌单id来修改数据库中playList图片。
        String filepath="e:/images/cover";
        File file1=new File(filepath);
        MultipartFile file=playListImgFormData.getFile();
        try {
            String imgName= UID.getUUID() +file.getOriginalFilename();
            file.transferTo(new File(file1, imgName));
            //生成图片路径
            String photoPath="http://localhost:8080/api/cover/"+imgName;
            int id=playListImgFormData.getId();
            //在更新前先将静态资源的图片数据删了
            PlayListDetail playListDetail=playListService.getPlayListDetail(id);
            if(playListDetail.getCoverImgUrl()!=null ){//如果之前没有图片路径存入新的！！
                String oldPhotoPath= playListDetail.getCoverImgUrl();
                String str=oldPhotoPath.replace("http://localhost:8080/api/cover","");
                File file2=new File(filepath+str);
                if(file2.delete()) {
                    System.out.println("图片删除成功！");
                } else {
                    System.out.println("图片删除失败。请检查路径是否正确，或者是否有足够的权限删除文件。");
                }
            }
            if(playListDetail.getIsPublic() == 1) {
                Recommend recommend = new Recommend();
                recommend.setId(playListDetail.getListId());
                recommend.setName(playListDetail.getName());
                recommend.setPicUrl(photoPath);
                playListService.updateRecommend(recommend);
            }
            //将路径存入数据库
            playListService.updateCover(photoPath,id+"");
        }catch (IOException e){
            throw new RuntimeException(e);
        }
        return Result.ok();
    }
    //删除歌单
    @RequestMapping("/playList/delplayList")
    @ResponseBody
    public Result deletePlayList(int id,@RequestHeader("Authorization") String token){
        //这里考虑到删歌单，附加要删歌单中的歌曲，这个是需要注意的！,这个传过来的id就是listId
        //容易的一点是两张表都是按照listId删除的！！！playlist and playlisttracks
        playListService.deletePlaylistById(id);
        playListService.delPlayListTracksByListId(id);
//        同步删除公共歌单
        playListService.delRecommend(id);
        return Result.ok();
    }
    //添加歌曲至歌单
    @RequestMapping("/playList/tracksAdd")
    @ResponseBody
    public Result addSongToPlayList(@Param("musicId") int musicId,@Param("playlistId") int playlistId){
        //前端传来的数据，一个是音乐的id，另外一个是要收藏音乐的目的歌单id
        //数据库的表设计的还行，这里直接向playlisttracks表中插入一条数据
        //首先是要查出来，有没有同一歌单有没有 重复的歌曲！！！
        if(playListService.findTrackInList(musicId, playlistId)!=null){//查到歌单歌曲有重复的
            return Result.error("目标歌单已经存在歌曲！");
        }
        //向playlisttracks表中插入这条数据
        int result=playListService.addSongByID(musicId,playlistId);
        if(result!=1){
            return Result.error();
        }
        return Result.ok();
    }
    //删除歌单中的歌曲
    @RequestMapping("/playList/delsongInp")
    @ResponseBody
    public Result deleteMusicFromList(int musicId,int playId,@RequestHeader("Authorization") String token){
        //这里设计表的时候还是和前端有点小小的差错，没事用过歌曲id就能删除歌单中的歌曲
        //这里也只是简单的去playlisttracks表中删除那一项数据，根据这两个参数，这次是必须的！！！！
        //之前没有考虑清楚为什么我们用上另外的一个参数。
        int result=playListService.deleteSongByID(musicId,playId);
        if(result!=1){
            return Result.error();
        }
        return Result.ok();
    }


    /**
     * 增加回复
     * @param uuid
     * @param message
     * @param listId
     * @return
     * @throws SocketException
     */
    @RequestMapping("/playList/addComment")
    @ResponseBody
    public Result addComment(String uuid ,String message , int listId){
        UserInfo userInfo = accountsService.getUserInfoByUUID(uuid);
        CommentInfo commentInfo = CommentUtil.createComment(uuid,message,userInfo,listId,"yyyy-MM-dd hh:mm");
        int res = playListService.addComment(commentInfo);
        if (res == 1) {
            return Result.ok("发布成功！").put("status", true);
        }
        return Result.error("发布失败，请稍后重试！").put("status", false);
    }

    /**
     * 增加回复
     * @param message
     * @param uuid
     * @param listId
     * @param lastId
     * @return
     * @throws SocketException
     */
    @RequestMapping("playList/addReply")
    @ResponseBody
    public Result addReply(String message,String uuid,int listId,int lastId) {
        UserInfo userInfo = accountsService.getUserInfoByUUID(uuid);
        CommentInfo commentInfo = CommentUtil.createComment(uuid,message,userInfo,listId,lastId,"yyyy-MM-dd hh:mm");
        int res = playListService.addReply(commentInfo);
        if(res == 1){
            return Result.ok("回复成功！").put("status",true);
        }
        return Result.error("回复失败，请稍后重试！").put("status",false);
    }

    /**
     * 获取当前表单下所有评论
     * @param listId
     * @return
     */
    @RequestMapping("/playList/getAllComment")
    @ResponseBody
    public Result getAllComment(String uuid,int listId){
        List<CommentInfo> commentInfoList = playListService.getAllComment(uuid,listId);
        return Result.ok().put("data",commentInfoList);
    }

    /**
     * 级联删除评论和回复
     * @param id
     * @return
     */
    @RequestMapping("/playList/delComment")
    @ResponseBody
    public Result delComment(int id){
        int res = playListService.delComment(id);
        if(res == 1){
            return Result.ok("删除成功！").put("data",true);
        }
        return Result.error("删除失败！").put("data",false);
    }

    @RequestMapping("/playList/support")
    @ResponseBody
    public Result support(int id,int isSupport ,String uuid){
        boolean isTrue = playListService.support(id,isSupport,uuid, id);
        if(isTrue){
            return Result.ok("点赞成功！").put("isSupport", true);
        }else return Result.error("点赞撤回！").put("isSupport", false);
    }

    /**
     * 评论头像，歌单头像点击信息返回
     * @param uuid
     * @return
     * @throws SocketException
     */
    @RequestMapping("/playList/getCommentOrPlayListUserInfo")
    @ResponseBody
    public Result getCommentUserInfo(String uuid) throws SocketException {
        UserInfo userInfo = accountsService.getUserInfoByUUID(uuid);
        userInfo.setPhotoPath(AddressInvertUtil.localHostReplace(userInfo.getPhotoPath()));

        List<PlayList> playLists = playListService.getUserPublicList(uuid);
        for (PlayList playList : playLists) {
            playList.setPicUrl(AddressInvertUtil.localHostReplace(playList.getPicUrl()));
        }
        return Objects.requireNonNull(Result.ok().put("userInfo", userInfo)).put("playLists",playLists);
    }

    /**
     * 公开歌单的收藏
     */
    @RequestMapping("/playList/addFavorites")
    @ResponseBody
    public Result addFavorites(String uuid,Integer listid){
        int res = playListService.addFavorites(uuid,listid);
        if(res == 1){
            return Result.ok("收藏成功！").put("isTrue",true);
        }
        return Result.error("收藏失败，请稍后重试！").put("isTrue",false);
    }

    @RequestMapping("/playList/removeFavorites")
    @ResponseBody
    public Result removeFavorites(String uuid,int listid){
        int res = playListService.removeFavorites(uuid,listid);
        if(res == 1){
            return Result.ok("移除成功！").put("isTrue",true);
        }
        return Result.error("移除失败，请稍后重试！").put("isTrue",false);
    }

    @RequestMapping("/playList/getUserFavorites")
    @ResponseBody
    public Result getUserFavorites(String uuid) throws SocketException {
        List<PlayList> playLists = playListService.getUserFavorites(uuid);
        for (PlayList playList : playLists) {
            playList.setPicUrl(AddressInvertUtil.localHostReplace(playList.getPicUrl()));
        }
        return Result.ok().put("playLists",playLists);
    }
}
